import axios, { AxiosError } from "axios";
import qs from "qs";
import { UserInfo } from "./user-info";
import { LocalUser } from "./local-user";
import { TokenInfo } from "./token-info";
import { UserFriendlyException } from "@/exceptions/IUserFriendlyException";

const loginUrl = process.env.AUTH_SERVER_BASE_URL + "/connect/token";
const logoutUrl = process.env.AUTH_SERVER_BASE_URL + "/connect/revocation";

export class UserManager {
  public static async loginAsync(userName: string, password: string) {
    try {
      const responseData = await axios.post(
        loginUrl,
        qs.stringify({
          grant_type: "password",
          client_id: "DeviceOpsServiceApp",
          client_secret: "1q2w3e*",
          username: userName,
          password: password,
        }),
        {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        }
      );
      const tokenInfo = responseData.data as TokenInfo;
      return new UserInfo(tokenInfo);
    } catch (err) {
      if (err instanceof AxiosError) {
        if (err.status === 400) {
          throw UserFriendlyException.createException(
            "用户名或密码错误。",
            err.status.toString(),
            err
          );
        } else if (err.status === 404) {
          throw UserFriendlyException.createException(
            "服务器不能访问。",
            err.status.toString(),
            err
          );
        } else if (err.code === "ERR_NETWORK") {
          throw UserFriendlyException.createException(
            "当前网络错误。",
            err.code.toString(),
            err
          );
        } else {
          throw err;
        }
      } else {
        throw err;
      }
    }
  }

  public static async logoutAsync() {
    try {
      const user = LocalUser.tryGetUserInfo();
      if (user == null) {
        return;
      }
      axios.post(
        logoutUrl,
        qs.stringify({
          token: user.tokenInfo.refresh_token,
          token_type_hint: "refresh_token",
          client_id: "DeviceOpsServiceApp",
          client_secret: "1q2w3e*",
        }),
        {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        }
      );
    } catch (err) {
      if (err instanceof AxiosError) {
        if (err.status === 404) {
          UserFriendlyException.createException(
            "服务器不能访问。",
            err.status.toString(),
            err
          );
        } else {
          throw err;
        }
      } else {
        throw err;
      }
    }
  }

  public static async refreshTokenAsync(refreshToken: string) {
    try {
      const responseData = await axios.post(
        loginUrl,
        qs.stringify({
          grant_type: "refresh_token",
          client_id: "DeviceOpsServiceApp",
          client_secret: "1q2w3e*",
          refresh_token: refreshToken,
        }),
        {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        }
      );

      const tokenInfo = responseData.data as TokenInfo;
      return new UserInfo(tokenInfo);
      // 更新用户信息后存储到本地。
    } catch (err) {
      if (err instanceof AxiosError) {
        if (err.status === 404) {
          throw UserFriendlyException.createException(
            "服务器不能访问。",
            err.status?.toString(),
            {}
          );
        } else {
          throw err;
        }
      } else {
        throw err;
      }
    }
  }
}
